import javax.microedition.lcdui.*;


public class Mapa extends Canvas{
	
	/**
	 * Atributos
	 */
	private int[][]matriz;
	private int width,height,tamc, robox,roboy,ultimo;
	private boolean tiene;
	private boolean pone;
	
	
	
	/**
	 * Constructor de la clase Mapa
	 * @param matriz
	 */
	public Mapa(int[][] matriz)
	{
		/**
		 * Inicializa los atributos de la clase
		 */
		this.matriz=matriz;
		this.robox=1;
		this.roboy=1;
		this.ultimo=1;
		this.pone=false;
		
		/**
		 * revisa que el robot este en la posición 1,1
		 * sino lo coloca en esa posición
		 */
		for(int i=0;i<10;i++)
			for(int j=0;j<10;j++)
				if(this.matriz[i][j]==4)
					this.matriz[i][j]=1;
		
		
		this.matriz[roboy][robox]=4;
		width=getWidth();
		height=getHeight();
		if (height<width)
			tamc=height/10;
		else
			tamc=width/10;
		

		
	}

	
	/**
	 * Procedimiento para pintar el mapa dependiendo de la matriz
	 */
	protected void paint(Graphics g) {
		// TODO Auto-generated method stub
		
		int color;
		
		
		/**
		 * Hace cuadritos de colores en el canvas dependiendo
		 * del valor que este en la posicion indicada de la matriz
		 */
		g.setColor(0);
		g.fillRect(0, 0, height, width);
		
		for(int i=0;i<10;i++)
			for(int j=0;j<10;j++)
			{
				color=matriz[i][j];
				if (color==2)
					g.setColor(255,0,0);
				else
					if(color==1)
						g.setColor(124, 252, 0);
					else
						if(color==3)
							g.setColor(139, 69, 19);
						else
							if(color==5)
								g.setColor(108,123,139);
							else
								g.setColor(192, 192, 192);
				
				g.fillRect(j*tamc, i*tamc, tamc, tamc);
				
				
			}
	}
	/**
	 * Método que mueve al robot hacia adelante
	 * el número de pasos enviados como parámetro
	 * @param pasos
	 */
	public void forward(int pasos)
	{
		boolean sigue=true;
		int i=1;
		/**
		 * Ciclo que termina cuando se hayan dado
		 * todos los pasos indicados o cuando el
		 * robot se encuentre con una pared.
		 */
		while((i<=pasos)&&(sigue))
		{	
			if((roboy-1)>=0)
				
			{
				if((matriz[roboy-1][robox]==1)||(matriz[roboy-1][robox]==5))
				{
					/**
					 * Revisa si tiene que poner un beacon o no
					 */
					if(pone)
					{
						matriz[roboy][robox]=5;
						pone=false;
					}
					else
						matriz[roboy][robox]=ultimo;
					/**
					 * Guarda el valor de la celda en la que esta el
					 * robot y coloca al robot en la celda actual
					 */
					roboy-=1;
					ultimo=matriz[roboy][robox];
					matriz[roboy][robox]=4;
					
				}
				else
					sigue=false;
			}
			i++;
		}
				
	}
	
	/**
	 * Método que mueve el robot hacia atrás
	 * el número de pasos indicados como parámetro
	 * @param pasos
	 */
	public void backward(int pasos)
	{
		/**
		 * Ciclo que termina cuando se hayan dado
		 * todos los pasos indicados o cuando el
		 * robot se encuentre con una pared.
		 */
		boolean sigue=true;
		int i=1;
		while((i<=pasos)&&(sigue))
		{	
			if((roboy+1)<10)
				
			{
				if((matriz[roboy+1][robox]==1)||(matriz[roboy+1][robox]==5))
				{
					/**
					 * Revisa si tiene que poner o no un beacon
					 */
					if(pone)
					{
						matriz[roboy][robox]=5;
						pone=false;
					}
					else
						matriz[roboy][robox]=ultimo;
					/**
					 * Guarda el valor de la celda en la que esta el
					 * robot y coloca al robot en la celda actual
					 */
					roboy+=1;
					ultimo=matriz[roboy][robox];
					matriz[roboy][robox]=4;
					
				}
				else
					sigue=false;
			}
			i++;
		}

	}
	
	/**
	 * Método que mueve el robot un paso hacia la izquierda
	 */
	public void left()
	{
		/**
		 * Revisa que el robot se pueda mover dentro de
		 * la matriz y que no haya nada obstruyendole el
		 * paso.
		 */
		if((robox-1)>=0)
		{
			if((matriz[roboy][robox-1]==1)||(matriz[roboy][robox-1]==5))
			{
				/**
				 * Revisa si hay que poner un beacon o no
				 */
				if(pone)
				{
					matriz[roboy][robox]=5;
					pone=false;
				}
				else
					matriz[roboy][robox]=ultimo;
				
				/**
				 * Guarda el valor de la celda en la que esta el
				 * robot y coloca al robot en la celda actual
				 */
				robox-=1;
				ultimo=matriz[roboy][robox];
				matriz[roboy][robox]=4;
				
				
			}
				
		}
		
	}
	
	/**
	 * Método que mueve el robot un paso hacia la derecha
	 */
	public void right()
	{
		/**
		 * Revisa que el robot se pueda mover dentro de
		 * la matriz y que no haya nada obstruyendole el
		 * paso.
		 */
		if((robox-1)<10)
		{
			if((matriz[roboy][robox+1]==1)||(matriz[roboy][robox+1]==5))
			{
				/**
				 * Revisa si hay que poner un beacon o no
				 */
				if(pone)
				{
					matriz[roboy][robox]=5;
					pone=false;
				}
				else
					matriz[roboy][robox]=ultimo;
				/**
				 * Guarda el valor de la celda en la que esta el
				 * robot y coloca al robot en la celda actual
				 */
				robox+=1;
				ultimo=matriz[roboy][robox];
				matriz[roboy][robox]=4;
				
				
			}
				
		}
	}

	/**
	 * Método que recoje un beacon si es posible
	 */
	public void pickUp()
	{
		/**
		 * Revisa que la última celda en la que se haya
		 * parado haya sido un beacon, si lo es cambia la
		 * bandera tiene a true y cambia el valor de la 
		 * ultima celda a "grama"
		 */
		if(ultimo==5)
		{
			tiene=true;
			ultimo=1;
		}
	}
	
	/**
	 * Método que pone un beacon si es posible
	 */
	public void putDown()
	{
		/**
		 * Revisa que la bandera tiene sea true
		 * si lo es indica que se debe poner un beacon
		 * y desactiva la bandera tiene.
		 */
		if(tiene)
		{
			tiene=false;
			pone=true;			
		}
	}
	
	
	/**
	 * Método que convierte un integer en string
	 * @param string
	 * @return
	 */
	private int str_Int(String string){
		/**
		 * Intenta convertir el parámetro en string
		 * si no se puede regresa -1 indicando error
		 */
		try {
			return Integer.parseInt(string);
		}
		catch(Exception e){
			return -1;
		}
		
		
	}
	
	/**
	 * Método que llama a la instrucción indicada
	 * @param inst
	 */
	public void  identificar(String inst){
		String letra1 = inst.substring(0,1);
		int param;
		
		/**
		 * Revisa que no sea end() indicador de fin
		 * de las instrucciones
		 */
		if (inst.equals("end()")){
			
		}
		else{
			if (letra1.equals("f")){
				if(inst.substring(0,8).equals("forward(")){
					if(inst.substring(9).equals(")")){
						param = str_Int(inst.substring(8,9));
						if (param != -1)
							forward(param);
					}
				}
			}
			
			if (letra1.equals("b")){
				if(inst.substring(0,9).equals("backward(")){
					if(inst.substring(10).equals(")")){
						param = str_Int(inst.substring(9,10));
						if (param != -1)
							backward(param);
					}
				}
			}
			
			if(inst.equals("left()")){
				left();
			}
		
			if(inst.equals("right()")){
				right();
			}		
		
			if(inst.equals("pickUp()")){
				pickUp();
			}
			
			if(inst.equals("putDown()")){
				putDown();
			}
			
			repaint();
		}
	}
	
	/**
	 * Método que regresa la matriz con los valores del mapa
	 * @return
	 */
	public int[][] getMatriz()
	{
		return(this.matriz);
	}
	
}
